package com.chessgame.model;

import java.util.ArrayList;
import java.util.List;

/**
 * 棋盘类，管理棋盘状态和游戏逻辑
 */
public class Board {
    private Piece[][] pieces;
    private List<Move> moveHistory;
    private boolean isRedTurn;

    public Board() {
        pieces = new Piece[9][10];
        moveHistory = new ArrayList<>();
        isRedTurn = true;
        initializeBoard();
    }

    private void initializeBoard() {
        // 初始化红方棋子
        pieces[0][9] = new Piece(PieceType.RED_CHARIOT, 0, 9);
        pieces[1][9] = new Piece(PieceType.RED_HORSE, 1, 9);
        pieces[2][9] = new Piece(PieceType.RED_ELEPHANT, 2, 9);
        pieces[3][9] = new Piece(PieceType.RED_ADVISOR, 3, 9);
        pieces[4][9] = new Piece(PieceType.RED_GENERAL, 4, 9);
        pieces[5][9] = new Piece(PieceType.RED_ADVISOR, 5, 9);
        pieces[6][9] = new Piece(PieceType.RED_ELEPHANT, 6, 9);
        pieces[7][9] = new Piece(PieceType.RED_HORSE, 7, 9);
        pieces[8][9] = new Piece(PieceType.RED_CHARIOT, 8, 9);
        pieces[1][7] = new Piece(PieceType.RED_CANNON, 1, 7);
        pieces[7][7] = new Piece(PieceType.RED_CANNON, 7, 7);
        pieces[0][6] = new Piece(PieceType.RED_SOLDIER, 0, 6);
        pieces[2][6] = new Piece(PieceType.RED_SOLDIER, 2, 6);
        pieces[4][6] = new Piece(PieceType.RED_SOLDIER, 4, 6);
        pieces[6][6] = new Piece(PieceType.RED_SOLDIER, 6, 6);
        pieces[8][6] = new Piece(PieceType.RED_SOLDIER, 8, 6);

        // 初始化黑方棋子
        pieces[0][0] = new Piece(PieceType.BLACK_CHARIOT, 0, 0);
        pieces[1][0] = new Piece(PieceType.BLACK_HORSE, 1, 0);
        pieces[2][0] = new Piece(PieceType.BLACK_ELEPHANT, 2, 0);
        pieces[3][0] = new Piece(PieceType.BLACK_ADVISOR, 3, 0);
        pieces[4][0] = new Piece(PieceType.BLACK_GENERAL, 4, 0);
        pieces[5][0] = new Piece(PieceType.BLACK_ADVISOR, 5, 0);
        pieces[6][0] = new Piece(PieceType.BLACK_ELEPHANT, 6, 0);
        pieces[7][0] = new Piece(PieceType.BLACK_HORSE, 7, 0);
        pieces[8][0] = new Piece(PieceType.BLACK_CHARIOT, 8, 0);
        pieces[1][2] = new Piece(PieceType.BLACK_CANNON, 1, 2);
        pieces[7][2] = new Piece(PieceType.BLACK_CANNON, 7, 2);
        pieces[0][3] = new Piece(PieceType.BLACK_SOLDIER, 0, 3);
        pieces[2][3] = new Piece(PieceType.BLACK_SOLDIER, 2, 3);
        pieces[4][3] = new Piece(PieceType.BLACK_SOLDIER, 4, 3);
        pieces[6][3] = new Piece(PieceType.BLACK_SOLDIER, 6, 3);
        pieces[8][3] = new Piece(PieceType.BLACK_SOLDIER, 8, 3);
    }

    public Piece getPieceAt(int x, int y) {
        return pieces[x][y];
    }

    public boolean isRedTurn() {
        return isRedTurn;
    }

    /**
     * 移动棋子
     * @param fromX 起始X坐标
     * @param fromY 起始Y坐标
     * @param toX 目标X坐标
     * @param toY 目标Y坐标
     * @return 移动是否成功
     */
    public boolean movePiece(int fromX, int fromY, int toX, int toY) {
        Piece piece = pieces[fromX][fromY];
        if (piece == null || piece.isRed() != isRedTurn) {
            return false;
        }

        if (!piece.isValidMove(this, toX, toY)) {
            return false;
        }

        // 记录移动历史
        Move move = new Move(fromX, fromY, toX, toY, pieces[toX][toY]);
        moveHistory.add(move);

        // 执行移动
        pieces[toX][toY] = piece;
        pieces[fromX][fromY] = null;
        piece.setPosition(toX, toY);

        // 检查移动后是否会导致己方将军
        if (isInCheck(piece.isRed())) {
            undoLastMove();
            return false;
        }

        // 切换回合
        isRedTurn = !isRedTurn;
        return true;
    }

    /**
     * 悔棋
     * @return 是否成功悔棋
     */
    public boolean undoLastMove() {
        if (moveHistory.isEmpty()) {
            return false;
        }

        Move lastMove = moveHistory.remove(moveHistory.size() - 1);
        Piece piece = pieces[lastMove.toX][lastMove.toY];

        // 恢复棋子位置
        pieces[lastMove.fromX][lastMove.fromY] = piece;
        pieces[lastMove.toX][lastMove.toY] = lastMove.capturedPiece;
        if (piece != null) {
            piece.setPosition(lastMove.fromX, lastMove.fromY);
        }

        // 切换回合
        isRedTurn = !isRedTurn;
        return true;
    }

    /**
     * 检查指定颜色方是否被将军
     * @param isRed 是否检查红方
     * @return 是否被将军
     */
    public boolean isInCheck(boolean isRed) {
        // 找到将/帅的位置
        Piece general = null;
        int generalX = -1, generalY = -1;
        for (int x = 0; x < 9; x++) {
            for (int y = 0; y < 10; y++) {
                Piece piece = pieces[x][y];
                if (piece != null && piece.isRed() == isRed && 
                    (piece.getType() == PieceType.RED_GENERAL || 
                     piece.getType() == PieceType.BLACK_GENERAL)) {
                    general = piece;
                    generalX = x;
                    generalY = y;
                    break;
                }
            }
            if (general != null) break;
        }

        if (general == null) return false;

        // 检查是否被其他棋子将军
        for (int x = 0; x < 9; x++) {
            for (int y = 0; y < 10; y++) {
                Piece piece = pieces[x][y];
                if (piece != null && piece.isRed() != isRed && 
                    piece.isValidMove(this, generalX, generalY)) {
                    return true;
                }
            }
        }

        return false;
    }

    /**
     * 检查指定颜色方是否被将死
     * @param isRed 是否检查红方
     * @return 是否被将死
     */
    public boolean isCheckmate(boolean isRed) {
        if (!isInCheck(isRed)) {
            return false;
        }

        // 尝试所有可能的移动来解除将军
        for (int fromX = 0; fromX < 9; fromX++) {
            for (int fromY = 0; fromY < 10; fromY++) {
                Piece piece = pieces[fromX][fromY];
                if (piece != null && piece.isRed() == isRed) {
                    for (int toX = 0; toX < 9; toX++) {
                        for (int toY = 0; toY < 10; toY++) {
                            if (piece.isValidMove(this, toX, toY)) {
                                // 尝试移动
                                Move move = new Move(fromX, fromY, toX, toY, pieces[toX][toY]);
                                pieces[toX][toY] = piece;
                                pieces[fromX][fromY] = null;
                                piece.setPosition(toX, toY);

                                boolean stillInCheck = isInCheck(isRed);

                                // 恢复位置
                                pieces[fromX][fromY] = piece;
                                pieces[toX][toY] = move.capturedPiece;
                                piece.setPosition(fromX, fromY);

                                if (!stillInCheck) {
                                    return false;
                                }
                            }
                        }
                    }
                }
            }
        }

        return true;
    }

    /**
     * 记录移动的内部类
     */
    private static class Move {
        int fromX, fromY, toX, toY;
        Piece capturedPiece;

        Move(int fromX, int fromY, int toX, int toY, Piece capturedPiece) {
            this.fromX = fromX;
            this.fromY = fromY;
            this.toX = toX;
            this.toY = toY;
            this.capturedPiece = capturedPiece;
        }
    }
}